#include "data_global.h"
#include "uart_cache.h"
#include "sqlite_link_list.h"

extern unsigned char dev_led_mask;
extern unsigned char dev_camera_mask;
extern unsigned char dev_buzzer_mask;
extern unsigned char dev_uart_mask;

extern pthread_cond_t cond_led;
extern pthread_cond_t cond_camera;
extern pthread_cond_t cond_buzzer;
extern pthread_cond_t cond_refresh;
extern pthread_cond_t cond_uart_cmd;
extern pthread_cond_t cond_sqlite;

extern pthread_mutex_t mutex_global;
extern pthread_mutex_t mutex_uart_cmd;
extern pthread_mutex_t mutex_led;
extern pthread_mutex_t mutex_buzzer;
extern pthread_mutex_t mutex_camera;
extern pthread_mutex_t mutex_slinklist;

extern char cgi_status;
extern int msgid;
extern struct env_info_clien_addr all_info_RT; 

extern uart_cache_list m0_cache_head, m0_cache_tail;

extern char recive_phone[12] ;
extern char center_phone[12] ;

struct setEnv
{
	int temMAX;
	int temMIN;
	int humMAX;
	int humMIN;
	int illMAX;
	int illMIN;
};

char *tel_num="18222385380";
char *message ="hurry up go home";
extern int dev_sms_fd;


int open_port(char *com_port);
int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits);
void send_message(char *tel,char *msg);


void *pthread_client_request (void *arg)
{
	key_t key;
	ssize_t msgsize;
	struct msg msgbuf;
	struct setEnv new;
	int sto_no;

	if ((key = ftok ("/app", 'g')) < 0)
	{
		perror ("ftok msgqueue");
		exit (-1);
	}
	if ((msgid = msgget (key, IPC_CREAT | IPC_EXCL | 0666)) < 0)
	{
		if(errno == EEXIST)
		{
			msgid = msgget (key,0666);
			return 0;
		} 
		else
		{
			perror ("msgget msgid");
			exit (-1);
		}
	}

	m0_cache_head = CreateEmptyCacheList ();
	m0_cache_tail = m0_cache_head;
	unsigned char *m0_temp;

	printf ("pthread_client_request is ok\n");
	while (1)
	{
		bzero (&msgbuf, sizeof (msgbuf));
				printf ("wait for the msg\n");
		msgsize = msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
				printf ("Get %ldL msg\n", msgbuf.msgtype);
				printf ("text[0] = %#x\n", msgbuf.text[0]);

		switch (msgbuf.msgtype)
		{
		case 1L:
			{
				pthread_mutex_lock (&mutex_led);
				dev_led_mask = msgbuf.text[0];
				pthread_cond_signal (&cond_led);
				pthread_mutex_unlock (&mutex_led);
				break;
			}
		case 2L:
			{
				pthread_mutex_lock (&mutex_buzzer);
				dev_buzzer_mask = msgbuf.text[0];
				printf("msgbuf.text[0] = %d \n",msgbuf.text[0]);
				pthread_cond_signal (&cond_buzzer);
				pthread_mutex_unlock (&mutex_buzzer);
				break;
			}
		case MSG_CAMERA:
			{
				pthread_mutex_lock (&mutex_camera);
				dev_camera_mask = msgbuf.text[0];
				pthread_cond_signal (&cond_camera);
				pthread_mutex_unlock (&mutex_camera);
				break;
			}
		case 4L:
			{
				//usleep (200000);
				pthread_mutex_lock (&mutex_uart_cmd);	
				m0_temp = (unsigned char *)malloc (sizeof (unsigned char));
				*m0_temp = msgbuf.text[0];
				printf("msgbuf.text from pc : 0x%#x\n",msgbuf.text[0]);
				InsertCacheNode (&m0_cache_tail, m0_temp);
				//dev_uart_mask = msgbuf.text[0];
				pthread_mutex_unlock (&mutex_uart_cmd);
				pthread_cond_signal (&cond_uart_cmd);
				break;
			}
		case 5L:
			{
				memcpy (&new, msgbuf.text + 1, 24);
				sto_no = msgbuf.text[0] - 48;
				printf ("sto_no = %d temMAX = %d, temMIN = %d, humMAX = %d, hunMIN = %d, illMAX = %d, illMIN = %d\n",
						sto_no, new.temMAX, new.temMIN, new.humMAX, new.humMIN, new.illMAX, new.illMIN);
				pthread_mutex_lock (&mutex_global);
				if (new.temMAX > 0 && new.temMAX > all_info_RT.storage_no[sto_no].temperatureMIN)
				{
					all_info_RT.storage_no[sto_no].temperatureMAX = new.temMAX;
			//		printf("new.temMAX =%d\n", new.temMAX);
				}
				if (new.temMIN > 0 && new.temMIN < all_info_RT.storage_no[sto_no].temperatureMAX)
				{
					all_info_RT.storage_no[sto_no].temperatureMIN = new.temMIN;
			//		printf("new.temMIN = %d\n", new.temMIN);
				}
				if (new.humMAX > 0 && new.humMAX > all_info_RT.storage_no[sto_no].humidityMIN)
				{
					all_info_RT.storage_no[sto_no].humidityMAX = new.humMAX;
			//		printf("new.humMAX = %d\n", new.humMAX);
				}
				if (new.humMIN > 0 && new.humMIN < all_info_RT.storage_no[sto_no].temperatureMAX)
				{
					all_info_RT.storage_no[sto_no].humidityMIN = new.humMIN;
			//		printf("new.humMIN = %d\n", new.humMIN);
				}
				if (new.illMAX > 0 && new.illMAX > all_info_RT.storage_no[sto_no].illuminationMIN)
				{
					all_info_RT.storage_no[sto_no].illuminationMAX = new.illMAX;
			//		printf("new.illMAX = %d\n", new.illMAX);
				}
				if (new.illMIN > 0 && new.illMIN < all_info_RT.storage_no[sto_no].illuminationMAX)
				{
					all_info_RT.storage_no[sto_no].illuminationMIN = new.illMIN;
			//		printf("new.illMIN = %d\n", new.illMIN);
				}
				pthread_mutex_lock (&mutex_slinklist);
				sqlite_InsertLinknode (ENV_UPDATE, all_info_RT, sto_no, 0);//0,0分别是仓库号和货物种类号
				pthread_mutex_unlock (&mutex_slinklist);
				pthread_cond_signal (&cond_sqlite);
				pthread_mutex_unlock (&mutex_global);
				pthread_cond_signal (&cond_refresh);
				break;
			}
#if 1
		case 10L:
			{
				int i = 0 , j = 0 ;
				for(i = 0  ; i < 11; i++)
				{
					recive_phone[i] = msgbuf.text[i]; 	
				}
				recive_phone[i] = '\0';
				printf("recive:%s\n",recive_phone);
				for(j = 0 ;msgbuf.text[i] != '\0' && j < 12; i++, j++)
				{
					center_phone[j] =  msgbuf.text[i];
				}
				center_phone[j] = '\0';
				printf("center:%s\n",center_phone);
	
					char buff[128]={0};
					//	char sbuff[128]={0};
					if ((dev_sms_fd = open_port(DEV_GPRS)) < 0){
						perror("open_port");
						return 1;
					}
					printf("dev_sms_fd :%d.\n",dev_sms_fd);
					if (set_com_config(dev_sms_fd, 9600, 8, 'N', 1) < 0){
						perror("set_com_config");
						return 1;
					}

					sleep(1);
					send_message(recive_phone,message);
					close(dev_sms_fd);

				pthread_mutex_lock (&mutex_slinklist);
				sqlite_InsertLinknode (ENV_UPDATE, all_info_RT, sto_no, 0);//0,0分别是仓库号和货物种类号
				pthread_mutex_unlock (&mutex_slinklist);
				pthread_cond_signal (&cond_sqlite);
				break;
			}
#endif 
#if 1
		case 11L:
			{
				char tmp[QUEUE_MSG_LEN] ={0};
				strcpy(tmp,msgbuf.text);
				char tmp1[100] = {0};
				char tmp2[100] = {0};
				int i = 0, j= 0;
				char cmd = 'f';
				for(i = 0 ; ; i++)
				{
					if(tmp[i] == 'n' || tmp[i] == 'f')
					{
						cmd = tmp[i];
						break;
					}
					tmp1[i] = tmp[i];	
				}
				tmp1[i] = '\0';
				printf("tmp1 : %s\n",tmp1);
				i++;
				for(j=0 ; tmp[i] != '\0'; i++, j++)
				{
					tmp2[j] = tmp[i];
				}
				tmp2[j] = '\0';
				printf("tmp2 : %s\n",tmp2);
				if(cmd == 'n')
				{
					static int status = 0;
					char ifcon[100] = "ifconfig wlan0 ";
					strcat(ifcon,tmp1);
					printf("string : %s\n",ifcon);
					system(ifcon);
					char gw[100] = "route add default gw ";
					strcat(gw,tmp2);
					system(gw);
					printf("gw : %s\n",gw);
					if(status == 0)
					{
						status = 1;
						system("mkdir /var/run/wpa_supplicant -p");
						system("wpa_supplicant -B -iwlan0 -c /etc/wpa-psk-tkip.conf");
						printf("wifi first start is ok\n");
					}
					else
					{
						system("ifconfig wlan0 up");
						printf("wifi start success\n");
					}
				}
				else if(cmd == 'f')
				{
					system("ifconfig wlan0 down");
					printf("wifi stop success\n");
				}
				break;
			}
#endif 
		default : break;
		}
	}

}



int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits)
{
	struct termios new_cfg, old_cfg;
	int speed;

	/*保存原有串口配置*/
	if (tcgetattr(fd, &old_cfg) != 0)
	{
		perror("tcgetattr");
		return -1;
	}

	new_cfg =old_cfg;

	/*配置为原始模式*/
	// cfmakeraw(&new_cfg);

	//本地连接和接收使能
	new_cfg.c_cflag |= CLOCAL | CREAD;

	//清除位掩码
	new_cfg.c_cflag &= ~CSIZE;
	//new_cfg.c_lflag |= ICANON;

	//取消硬件流控制
	new_cfg.c_cflag &= ~CRTSCTS;

	//忽略奇偶校验错误
	new_cfg.c_iflag |= IGNPAR;

	//取消将接收到的CR（回车符）转换为NL（换行符）和启动输出软件流控
	new_cfg.c_iflag &= ~(ICRNL | IXON);

	/*设置波特率*/
	switch (baud_rate)
	{
		case 2400:
			{
				speed = B2400;
				break; 
			}
		case 4800:
			{
				speed = B4800;
				break;
			}
		case 9600:
			{
				speed = B9600;
				break;
			}
		case 19200:
			{
				speed = B19200;
				break;
			}
		case 38400:
			{
				speed = B38400;
				break;
			}

		default:
		case 115200:
			{
				speed = B115200;
				break;
			}
	}

	cfsetispeed(&new_cfg, speed);
	cfsetospeed(&new_cfg, speed);

	/*设置数据位*/
	switch (data_bits)
	{
		case 7:
			{
				new_cfg.c_cflag |= CS7;
				break;
			}   

		default:	
		case 8:
			{
				new_cfg.c_cflag |= CS8;
				break;
			}
	}

	/*设置奇偶校验位*/
	switch (parity)
	{
		default:
		case 'n':
		case 'N':
			{
				new_cfg.c_cflag &= ~PARENB;
				new_cfg.c_iflag &= ~INPCK;
				break;
			}

		case 'o':
		case 'O':
			{
				new_cfg.c_cflag |= (PARODD |PARENB);
				new_cfg.c_iflag |= INPCK;
				break;
			}

		case 'e':
		case 'E':
			{
				new_cfg.c_cflag |= PARENB;
				new_cfg.c_cflag &= ~PARODD;
				new_cfg.c_iflag |= INPCK;
				break;
			}

		case 's':
		case 'S':
			{
				new_cfg.c_cflag &= ~PARENB;
				new_cfg.c_cflag &= ~CSTOPB;
				break;
			}
	}

	/*设置停止位*/
	switch (stop_bits)
	{
		default:
		case 1:
			{
				new_cfg.c_cflag &= ~CSTOPB;
				break;
			}   	

		case 2:
			{
				new_cfg.c_cflag |= CSTOPB;
				break;
			}
	}

	new_cfg.c_oflag = 0;
	new_cfg.c_lflag = 0;

	/*设置等待时间和最小接收字符*/
	//new_cfg.c_cc[VTIME] = 0;
	//new_cfg.c_cc[VMIN] = 0;

	// tcflush(fd, TCIFLUSH);
	if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
	{
		perror("tcsetattr");
		return -1;
	}

	return 0;


}



int open_port(char *com_port)
{
	int fd;

	/*打开串口*/
	fd = open(com_port, O_RDWR|O_NOCTTY|O_NDELAY);
	if (fd < 0)
	{
		perror("open serial port");
		return -1;
	}

	/*恢复串口阻塞状态*/
	if (fcntl(fd, F_SETFL, 0) < 0)
	{
		perror("fcntl F_SETFL\n");
	}

	/*判断是否为终端设备*/
	if (isatty(fd) == 0)
	{
		perror("This is not a terminal device");
	}

	return fd;
}


void send_message(char *tel,char *msg)
{
	printf("enter send_message .....\n");
	int n=0,ret=0,num=0;
	char end=26;
	char buff[128]={0};

	memset(buff,0,128);//测试串口是否正常工作，尽可能的多判断返回值
	strcpy(buff,"AT\n");
	write (dev_sms_fd,buff,strlen(buff));
	read(dev_sms_fd,buff,128);		
	if(strncmp(buff,"OK",2)){
		printf("serial port connected success \n");	
	}else{
		printf("serial port connected failed  \n");
	}	
	usleep(10000);		

	memset(buff,0,128);								
	strcpy(buff,"AT+CPIN?\n");//查询是否检测到SIM卡
	write (dev_sms_fd,buff,strlen(buff));          								
	read(dev_sms_fd,buff,128);
	printf("set coding type success,SIM卡成功检测到.\n");				
	usleep(10000);


	memset(buff,0,128);									
	strcpy(buff,"AT+CMGF=1\n");         //设置短信发送模式
	write (dev_sms_fd,buff,strlen(buff));  // CMGF :0(默认)：PDU模式 1：文本模式
	read(dev_sms_fd,buff,128);
	if(strncmp(buff,"OK",2)){
		printf("set message type success \n");
	}else{
		printf("set message type failed\n");
	}				
	usleep(100000);

	memset(buff,0,128);
	strcpy(buff,"AT+CSMP=17,167,0,240\n");         //参数4：241 短信存在sim卡中 240直接在终端显示			
	write (dev_sms_fd,buff,strlen(buff));
	read(dev_sms_fd,buff,128);usleep(10000);
	printf("message save at sim card!\n");
	usleep(100000);

	memset(buff,0,128);
	strcpy(buff,"AT+CMGDA=6\n");        			 //删除之前发送的信息与指令		
	write (dev_sms_fd,buff,strlen(buff));					
	read(dev_sms_fd,buff,128);
	if(strncmp(buff,"OK",2)){
		printf("delect message success!\n");				
	}else{
		printf("delect failed!\n");		
	}						

	memset(buff,0,128);
	sprintf(buff,"AT+CMGS=\"%s\"",tel);  //发送短信
	strcat(buff,"\n");
	write (dev_sms_fd,buff,strlen(buff));
	read(dev_sms_fd,buff,128);
	if(strncmp(buff,">",1))
	{
		if(message=='\0')
		{
			printf("please input the message information :");					
			scanf("%s",buff);					
			write(dev_sms_fd,buff,strlen(buff));					
			read(dev_sms_fd,buff,128);	
			write(dev_sms_fd,&end,1);
			read(dev_sms_fd,buff,128);
		}else{
			strcpy(buff,message);
			write(dev_sms_fd,buff,strlen(buff));					
			read(dev_sms_fd,buff,128);	
			write(dev_sms_fd,&end,1);
			read(dev_sms_fd,buff,128);	
		}

		n=strlen(buff);
		if(strncmp(&buff[n-1],"O",1)&&strncmp(&buff[n],"K",1)){
			printf("send message success :%s\n",msg);
		}else{
			printf("send message failed\n");
		}
		sleep(1);
	}else{					
		printf("send message failed!\n");
	}	
	sleep(2);
	return ;
}


